#include "SHA512.h"
#include "TestBase.h"
#include <string>

#ifdef WIN32
#include <windows.h>
#else
#include <sys/time.h>
#endif

unsigned long long GetTime()
{
#ifdef WIN32
	LARGE_INTEGER tps, tick, time;
	QueryPerformanceFrequency(&tps);
	QueryPerformanceCounter(&tick);
	time.QuadPart = tick.QuadPart/tps.QuadPart;
	return (unsigned long long)((time.QuadPart * 1000000) + (tick.QuadPart / (tps.QuadPart / 1000000)));
#else
	timeval tv;
	gettimeofday(&tv, NULL);
	return (unsigned long long)((tv.tv_sec * 1000000) + (tv.tv_usec));
#endif
}

TestBase::TestBase()
{
	info.Name = "CryptoSystem Test 2 - SHA512 speed test";
	info.Category = 0x3102;
	info.CategoryName = "CryptoSystem";
	info.File = __FILE__;
}

bool TestBase::Run()
{
#ifdef WIN32
	SetThreadAffinityMask(GetCurrentThread(), 1); // time counters between threads cannot be assured to be in sync, force to 1st core to work around
#endif
	unsigned char output[64];
	const char* buf;
	StateSHA512 state;
	int i, len;
	unsigned long long s, e;
	std::string msg;
	s = GetTime();
	SHA512_Init(&state);
	SHA512_Update(&state, NULL, 0);
	SHA512_Final(&state, output);
	e = GetTime();
	std::cout << "** SHA512 speed test **" << std::endl;
	std::cout << "Empty message   : " << (e - s) << "us" << std::endl;
	i = 100;
	while (i--)
	{
		msg += "a";
	}
	len = msg.length();
	buf = msg.c_str();
	s = GetTime();
	SHA512_Init(&state);
	SHA512_Update(&state, buf, len);
	SHA512_Final(&state, output);
	e = GetTime();
	std::cout << "100 characters  : " << (e - s) << "us" << std::endl;
	i = 1000;
	while (i--)
	{
		msg += "a";
	}
	len = msg.length();
	buf = msg.c_str();
	s = GetTime();
	SHA512_Init(&state);
	SHA512_Update(&state, buf, len);
	SHA512_Final(&state, output);
	e = GetTime();
	std::cout << "1000 characters : " << (e - s) << "us" << std::endl;
	i = 1500;
	while (i--)
	{
		msg += "a";
	}
	len = msg.length();
	buf = msg.c_str();
	s = GetTime();
	SHA512_Init(&state);
	SHA512_Update(&state, buf, len);
	SHA512_Final(&state, output);
	e = GetTime();
	std::cout << "1500 characters : " << (e - s) << "us" << std::endl;
	return true;
}